﻿
//++++++++++++++++++++++++++++++++++++++++
//2012.3.31
//107行, //if( Config.GetCPU() == CPUType.PC80X86 ) {
//去掉这个,这样对于任何CPU,读取地址都要区分原变量类型: code static local

namespace n_SuperASM
{
using System;
using n_AddressList;
using n_CharType;
using n_Code1;
using n_ET;
using n_FunctionList;
using n_Malloc;
using n_VarList;
using n_VarType;
using n_VdataList;
using n_WordList;
using n_Config;
using n_ConstString;
using n_CDebug;
using n_MemberType;

public static class SuperASM
{
	//转换为超级汇编指令集
	public static void Run( int FuncIndex, string Source )
	{
		FunctionIndex = FuncIndex;
		string[] Line = Source.Split( '\n' );
		int Level = 1;
		
		//分配变量形参地址 (如果是用户空间函数则不需要分配形参)
		if( !FunctionList.Get( FuncIndex ).UserSpace ) {
			string VarIndex = FunctionList.Get( FuncIndex ).VarIndexList;
			if( VarIndex != null ) {
				string[] VarCut = VarIndex.Split( ' ' );
				for( int i = 0; i < VarCut.Length; ++i ) {
					SetAddress( int.Parse( VarCut[ i ] ) );
				}
			}
		}
		
		//逐行处理虚拟指令
		for( int i = 0; i < Line.Length; ++i ) {
			if(Line[ i ] == "#语句层加" ) {
				++Level;
				continue;
			}
			if(Line[ i ] == "#语句层减" ) {
				--Level;
				for( int removeIndex = 0; removeIndex < VarList.length; ++removeIndex ) {
					if( VarList.Get( removeIndex ).Level > Level &&
						VarList.Get( removeIndex ).ActiveType == "local" &&
						VarList.GetAddr( removeIndex ) != null ) {
						AddressList.RemoveVar( removeIndex );
					}
				}
				continue;
			}
			//处理内嵌汇编
			if( Line[ i ].StartsWith( "#内嵌汇编 " ) ) {
				string s = asm( Line[ i ], FuncIndex );
				if( s != null ) {
					Malloc.Result.Append( s + "\n" );
				}
				continue;
			}
			//处理内嵌汇编
			if( Line[ i ].StartsWith( "#系统标志 " ) ) {
				string Name = Line[ i ].Split( ' ' )[ 1 ];
				Malloc.Result.Append( "系统标志 " + Name + "\n" );
				Debug.Deal( Name );
				continue;
			}
			//处理变量定义, 设置地址(不再推迟到使用时再申请地址, 不安全)
			if( Line[ i ].StartsWith( "#定义变量 " ) ) {
				string[] WordList = Line[ i ].Split( ' ' );
				SetAddress( int.Parse( WordList[ 2 ] ) );
				continue;
			}
			//处理转移参数
			if( Line[ i ].StartsWith( "#转移参数 " ) ) {
				string[] WordList = Line[ i ].Split( ' ' );
				int temIndex = int.Parse( WordList[ 1 ] );
				Malloc.Result.Append( "转移参数_" + VarType.GetASMType( VarList.Get( temIndex ).Type ) + "\n" );
				continue;
			}
			//忽略基础指令
			if( Line[ i ].StartsWith( "#" ) ) {
				Malloc.Result.Append( Line[ i ].Remove( 0, 1 ) + "\n" );
				continue;
			}
			
			//进行常量赋值优化
			if( Line[ i ].StartsWith( "常量赋值" ) ) {
				if( i + 1 < Line.Length && Line[ i + 1 ].StartsWith( "#转移参数" ) ) {
					Line[ i + 1 ] = "B" + Line[i];
					i = i + 1;
				}
			}
			
			/*
			常量赋值 483 #1
			#转移参数 483
			#禁用中断
			加载_0_static 101
			写入分量 101 101 483 #5
			保存_0_static 101
			#启用中断
			*/
			//进行IO口赋值优化
			if( Config.GetCPU().StartsWith( n_CPUType.CPUType.MEGA_X ) && Config.OptimizeFlag == 1 && Line[ i ].StartsWith( "B常量赋值" ) ) {
				string[] temps = Line[ i ].Split( ' ' );
				int CVarIndex = int.Parse( temps[ 1 ] );
				if( VarList.Get( CVarIndex ).Type == VarType.BaseType.Bit ) {
					if( i + 1 < Line.Length && Line[ i + 1 ].StartsWith( "#禁用中断" ) &&
					    i + 2 < Line.Length && Line[ i + 2 ].StartsWith( "加载_0_static" ) &&
					    i + 3 < Line.Length && Line[ i + 3 ].StartsWith( "写入分量" ) &&
					    i + 4 < Line.Length && Line[ i + 4 ].StartsWith( "保存_0_static" ) &&
					    i + 5 < Line.Length && Line[ i + 5 ].StartsWith( "#启用中断" ) ) {
						
						string[] tempV = Line[ i + 3 ].Split( ' ' );
						int TVarIndex = int.Parse( tempV[1] );
						int TAddr = int.Parse( VarList.Get( TVarIndex ).Address ) - 0x20;
						int TLocation = int.Parse( tempV[4].Remove( 0, 1 ) );
						
						if( VarList.Get( TVarIndex ).ActiveType == "static" ) {
							if( TAddr < 0x20 ) {
								string Oper = temps[2] == "#0" ? "内嵌汇编 cbi": "内嵌汇编 sbi";
								Malloc.Result.Append( Oper + " " + TAddr + "," + TLocation + "\n" );
								i = i + 5;
								continue;
							}
							else {
								//... 这里可以再优化
								//n_OS.VIO.Show( "1  " + VarList.Get( TVarIndex ).ToString() );
							}
						}
						else {
							//... 这里可以再优化
							//n_OS.VIO.Show( "2  " + VarList.Get( TVarIndex ).ToString() );
						}
					}
				}
			}
			//2014.1.20 词列表, 遍历词列表, 先记录新变量, 再删除旧变量, 注意这个顺序不能反!!!
			//因为在一个表达式中出现未分配地址的局部变量, 导致复合运算失效, 其实对于赋值运算也是失效,
			//只是赋值运算比较特殊而已!!! 
			string[] Word = Line[ i ].Split( ' ' );
			
			if( Config.GetCPU().StartsWith( n_CPUType.CPUType.MEGA_X ) || Config.GetCPU() == n_CPUType.CPUType.VM ) {
				//记录新变量
				for( int k = 1; k < Word.Length; ++k ) {
					if( !Word[ k ].StartsWith( "#" ) ) {
						int ni = int.Parse( Word[ k ] );
						if( VarList.GetAddr( ni ) == null ) {
							SetAddress( int.Parse( Word[ k ] ) );
						}
						//处理变量多线程访问
						DealIntVar( FuncIndex, ni );
					}
				}
				//释放无效变量
				for( int k = 2; k < Word.Length; ++k ) {
					if( !Word[ k ].StartsWith( "#" ) &&	VarList.Get( int.Parse( Word[ k ] ) ).ActiveType == "temp" ) {
						int LIndex = int.Parse( Word[ k ] );
						
						//如果是复合的变量, 忽略一次, 下次释放
						if( VarList.Get( LIndex ).IsComp ) {
							VarList.Get( LIndex ).IsComp = false;
							continue;
						}
						AddressList.RemoveVar( LIndex );
					}
				}
			}
			else if( Config.GetCPU().StartsWith( n_CPUType.CPUType.MCS_X ) ) {
				//释放无效变量
				for( int k = 2; k < Word.Length; ++k ) {
					if( !Word[ k ].StartsWith( "#" ) &&	VarList.Get( int.Parse( Word[ k ] ) ).ActiveType == "temp" ) {
						int LIndex = int.Parse( Word[ k ] );
						
						//如果是复合的变量, 忽略一次, 下次释放
						if( VarList.Get( LIndex ).IsComp ) {
							VarList.Get( LIndex ).IsComp = false;
							continue;
						}
						AddressList.RemoveVar( LIndex );
					}
				}
				//记录新变量
				for( int k = 1; k < Word.Length; ++k ) {
					if( !Word[ k ].StartsWith( "#" ) && VarList.GetAddr( int.Parse( Word[ k ] ) ) == null ) {
						SetAddress( int.Parse( Word[ k ] ) );
					}
				}
			}
			else {
				n_OS.VIO.Show( "<SuperASM.Run> 未知的CPU类型: " + Config.GetCPU() );
			}
			
			//生成超级汇编指令
			Malloc.Result.Append( TurnToSuperASM( Line[ i ] ) + "\n" );
		}
	}
	
	//把一个虚拟指令转换到中间汇编指令
	static string TurnToSuperASM( string Line )
	{
		string[] Cut = Line.Split( ' ' );
		string Oper = Cut[ 0 ];
		
		//如果是读取地址运算, 把变量索引替换成对应地址, 加上 #
		if( Oper == "读取地址" ) {
			int VarIndex = int.Parse( Cut[ 2 ].Remove( 0, 1 ) );
			
			string avarType = VarList.Get( VarIndex ).Type;
			
			string aStoreType = VarType.GetStoreType( avarType );
			int StoreIndex = VdataList.GetIndex( aStoreType );
			
			if( VarType.StoreTypeisVcode( avarType ) ) {
				Oper += "_code";
			}
			else if( VarType.StoreTypeisVbase( avarType ) ) {
				Oper += "_" + VarList.Get( VarIndex ).ActiveType;
				
				//if( VarList.Get( VarIndex ).ActiveType == n_MemberType.MemberType.StoreType.Temp ) {
				//	Oper += "_" + n_MemberType.MemberType.StoreType.Local;
				//}
				//else {
				//	Oper += "_" + VarList.Get( VarIndex ).ActiveType;
				//}
			}
			else {
				Oper += "_vdata";
			}
			if( VarList.GetAddr( VarIndex ) == null ) {
				SetAddress( VarIndex );
			}
			Cut[ 2 ] = "#" + VarList.GetAddr( VarIndex );
		}
		//判断赋值运算是否改变了临时变量
		if( Oper == "=" ) {
			int ii = int.Parse( Cut[ 1 ] );
			if( VarList.Get( ii ).ActiveType == "temp" &&
			    !VarList.Get( ii ).IgnoreWriteError &&
			    (!VarType.isRefer( VarList.Get( ii ).Type ) || !VarList.Get( ii ).EnableWrite ) ) {
				ET.WriteParseError( VarList.Get( ii ).Location, "临时变量的值不能被改变" );
			}
		}
		//把所有变量的索引置换为变量地址
		string Var = "";
		string StoreType = "";
		for( int i = 1; i < Cut.Length; ++i ) {
			if( Cut[ i ] == "#" ) {
				continue;
			}
			if( Cut[ i ].StartsWith( "#" ) ) {
				Cut[ i ] = Cut[ i ].Remove( 0, 1 );
				Var += " " + Cut[ i ];
				continue;
			}
			int VarIndex = int.Parse( Cut[ i ] );
			Oper += "_" + VarType.GetASMType( VarList.Get( VarIndex ).Type );
			Var += " " + VarList.GetAddr( VarIndex );
			StoreType += " " + VarList.Get( VarIndex ).ActiveType;
		}
		return Oper + Var + StoreType;
	}
	
	//内嵌汇编
	static string asm( string Line, int FuncIndex )
	{
		int Index = int.Parse( Line.Split( ' ' )[ 1 ] );
		string asm = WordList.GetWord( Index );
		if( !asm.StartsWith( "\"" ) || !asm.EndsWith( "\"" ) ) {
			ET.WriteParseError( Index, "内嵌汇编的格式不对: <" + asm + ">" );
			return null;
		}
		
		if( !Config.GetCPU().StartsWith( n_CPUType.CPUType.MCS_X ) ) {
			if( asm.IndexOf( ":" ) != -1 && asm.IndexOf( "@" ) == -1 ) {
				ET.WriteParseError( Index, "内嵌汇编中的标号应加上@前缀: <" + asm + ">" );
				return null;
			}
			//替换汇编中的函数名索引
			if( n_Config.Config.GetCPU().StartsWith( n_CPUType.CPUType.MEGA_X ) ) {
				asm = asm.Replace( "@", "ASMF" + FuncIndex + "_" );
			}
		}
		
		
		asm = asm.Substring( 1, asm.Length - 2 ) + " ";
		int StartIndex = asm.IndexOf( "&" );
		if( StartIndex == -1 ) {
			return "内嵌汇编 " + asm;
		}
		int EndIndex = StartIndex + 1;
		while( EndIndex < asm.Length ) {
			if( !CharType.isLetterOrNumber( asm[ EndIndex ] ) &&
			     asm[ EndIndex ] != '#' &&
				 asm[ EndIndex ] != '.' &&
			     asm[ EndIndex ] != '+' &&
			     asm[ EndIndex ] != '-' &&
			     asm[ EndIndex ] != '*' &&
			     asm[ EndIndex ] != '/' &&
			     asm[ EndIndex ] != '%' ) {
				break;
			}
			++EndIndex;
		}
		--EndIndex;
		string Start = asm.Remove( StartIndex );
		string Mid = asm.Substring( StartIndex + 1, EndIndex - StartIndex );
		string End = asm.Remove( 0, EndIndex + 1 );
		
		string[] NameCut = null;
		string Oper = null;
		if( Mid.IndexOf( '+' ) != -1 ) {
			NameCut = Mid.Split( '+' );
			Oper = "+";
		}
		else if( Mid.IndexOf( '-' ) != -1 ) {
			NameCut = Mid.Split( '-' );
			Oper = "-";
		}
		else if( Mid.IndexOf( '*' ) != -1 ) {
			NameCut = Mid.Split( '*' );
			Oper = "*";
		}
		else if( Mid.IndexOf( '/' ) != -1 ) {
			NameCut = Mid.Split( '/' );
			Oper = "/";
		}
		else if( Mid.IndexOf( '%' ) != -1 ) {
			NameCut = Mid.Split( '%' );
			Oper = "%";
		}
		else {
			NameCut = new string[ 1 ];
			NameCut[ 0 ] = Mid;
			Oper = null;
		}
		//判断是否为汇编调用C函数
		if( asm.StartsWith( "call " ) ) {
			int AsmCallIndex = FunctionList.GetIndex( NameCut[ 0 ] );
			if( AsmCallIndex == -1 ) {
				ET.WriteParseError( Index, "内嵌汇编中调用了未定义的函数: " + NameCut[ 0 ] );
				return null;
			}
			return "内嵌汇编 call " + Config.PreLabel.Function + AsmCallIndex;
		}
		//处理变量地址计算
		int VarIndex = VarList.GetLocalIndex( FunctionIndex, NameCut[ 0 ] );
		if( VarIndex == -1 ) {
			string UnitName = FunctionList.Get( FunctionIndex ).UnitName;
			VarIndex = VarList.GetStaticIndex( UnitName + "." + NameCut[ 0 ] );
			if( VarIndex == -1 ) {
				ET.WriteParseError( Index, "内嵌汇编中引用了未定义的变量: " + Mid );
				return null;
			}
			if( VarList.Get( VarIndex ).isConst ) {
				ET.WriteParseError( Index, "内嵌汇编中不允许访问常量: " + Mid );
				return null;
			}
		}
		//获取地址
		string sAddr = VarList.GetAddr( VarIndex );
		int Addr = -1;
		if( sAddr != null ) {
			if( sAddr.StartsWith( "#macro" ) ) {
				string[] BitAddress = sAddr.Split( ' ' );
				int BitIndex = int.Parse( BitAddress[1] );
				int BitAddr = int.Parse( VarList.GetAddr( BitIndex ) ) - 0x20;
				return "内嵌汇编 " + Start + BitAddr + "," + BitAddress[2] + End;
			}
			else {
				Addr = int.Parse( sAddr );
			}
		}
		if( Addr == -1 ) {
			SetAddress( VarIndex );
			Addr = int.Parse( VarList.GetAddr( VarIndex ) );
		}
		
//		string sAddr = VarList.GetAddr( VarIndex );
//		if( sAddr == null ) {
//			ET.WriteParseError( Index, "内嵌汇编中引用了未初始化的变量: " + Mid );
//			return null;
//		}
//		int Addr = int.Parse( sAddr );
//		if( Addr == -1 ) {
//			ET.WriteParseError( Index, "内嵌汇编中引用了未初始化的变量: " + Mid );
//			return null;
//		}
		
		if( NameCut.Length != 1 && NameCut.Length != 2 ) {
			ET.WriteParseError( Index, "内嵌汇编的引用变量格式不正确: " + asm );
			return null;
		}
		string SecondValue = null;
		int iSecondValue = 0;
		if( Oper != null ) {
			string TempType = null;
			SecondValue = ConstString.GetValue( ref TempType, NameCut[ 1 ], Index );
			if( SecondValue == null ) {
				Oper = null;
			}
			else {
				iSecondValue = int.Parse( SecondValue );
			}
		}
		if( Oper == "+" ) {
			Addr += iSecondValue;
		}
		else if( Oper == "-" ) {
			Addr -= iSecondValue;
		}
		else if( Oper == "*" ) {
			Addr *= iSecondValue;
		}
		else if( Oper == "/" ) {
			Addr /= iSecondValue;
		}
		else if( Oper == "%" ) {
			Addr %= iSecondValue;
		}
		return "内嵌汇编 " + Start + Addr + End;
	}
	
	//设置地址
	static void SetAddress( int VarIndex )
	{
		string Type = VarList.Get( VarIndex ).Type;
		if( Type == VarType.Void ) {
			return;
		}
		string VdataName = VarType.GetStoreType( Type );
		int VdataIndex = VdataList.GetIndex( VdataName );
		if( VdataIndex == -1 ) {
			ET.WriteParseError( VarList.Get( VarIndex ).Location, "设置变量地址时发现未定义的虚拟数据类型:" + VdataName );
			return;
		}
		if( !VdataList.Get( VdataIndex ).AutoAllot ) {
			return;
		}
		int Width = VarType.GetSize( Type );
		int Addr = AddressList.ApplyVarAddress( Type );
		if( Addr == -1 ) {
			ET.WriteParseError( VarList.Get( VarIndex ).Location, "变量地址分配溢出" );
			return;
		}
		VarList.Get( VarIndex ).Address = Addr.ToString();
		for( int i = 0; i < Width; ++i ) {
			AddressList.UsedAddressList[ VdataIndex ][ FunctionIndex ] += ( Addr + i ) + " ";
		}
		if( AddressList.MaxUsedAddressList[ VdataIndex ][ FunctionIndex ] < Addr + Width - 1 ) {
			AddressList.MaxUsedAddressList[ VdataIndex ][ FunctionIndex ] = Addr + Width - 1;
		}
	}
	
	//处理当前函数的线程变量
	static void DealIntVar( int cfi, int var )
	{
		//提取到读写共同的接口
		bool cisInt = false;
		
		//中断标志设置
		if( FunctionList.Get( cfi ).isInter ) {
			cisInt = true;
			
			if( VarList.Get( var ).UsedInterFincID != -1 && VarList.Get( var ).UsedInterFincID != cfi ) {
				VarList.Get( var ).UsedInterFincID = -2;
			}
			else {
				VarList.Get( var ).UsedInterFincID = cfi;
			}
		}
		else {
			if( VarList.Get( var ).UsedInterFincID != -1 && VarList.Get( var ).UsedInterFincID != -3 ) {
				VarList.Get( var ).UsedInterFincID = -2;
			}
			else {
				if( !n_Param.Param.isSafe ) {
					VarList.Get( var ).UsedInterFincID = -3;
				}
			}
		}
		//判断是否产生了冲突
		if( VarList.Get( var ).UsedInterFincID != -1 ) {
			
			if( VarList.Get( var ).UsedInterFincID != cfi && !(VarList.Get( var ).UsedInterFincID == -3 && !cisInt ) ) {
				
				/*
				string intFunc = "多个中断函数";
				if( VarList.Get( var ).UsedInterFincID != -2 ) {
					if( VarList.Get( var ).UsedInterFincID != -2 ) {
						intFunc = "用户态函数";
					}
					else {
						intFunc = FunctionList.Get( VarList.Get( var ).UsedInterFincID ).FunctionName;
					}
				}
				
				string cFunc = FunctionList.Get( cfi ).FunctionName;
				
				n_OS.VIO.Show( "函数 <" + cFunc + "> 使用了多线程变量: <" + VarList.Get( var ).Name + "> (产生使用冲突的其他线程函数: " + intFunc + ")" );
				*/
				VarList.Get( var ).MultAccessError = true;
			}
		}
	}
	
	static int FunctionIndex;
}
}
